<html>
<head>
<style>
  .ace_editor {
    border: 0;
    width: auto;
    height: 100%;
    margin: 0;
    top:0;
    right:0;
    bottom:0;
    left:0;
    z-index: 10000;
    touch-action: none;
  }

  body {
    padding: 0px;
    margin: 0px;
    overflow: hidden;
    -ms-overflow-style: scrollbar;
  }
</style>
</head>
<body>
<textarea id="source">package com.sencha.gxt.explorer.client.chart;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor.Path;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.chart.client.chart.Chart;
import com.sencha.gxt.chart.client.chart.Chart.Position;
import com.sencha.gxt.chart.client.chart.Legend;
import com.sencha.gxt.chart.client.chart.axis.CategoryAxis;
import com.sencha.gxt.chart.client.chart.axis.NumericAxis;
import com.sencha.gxt.chart.client.chart.series.LineSeries;
import com.sencha.gxt.chart.client.chart.series.Primitives;
import com.sencha.gxt.chart.client.draw.Color;
import com.sencha.gxt.chart.client.draw.RGB;
import com.sencha.gxt.chart.client.draw.path.PathSprite;
import com.sencha.gxt.chart.client.draw.sprite.Sprite;
import com.sencha.gxt.chart.client.draw.sprite.TextSprite;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.shared.LabelProvider;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.PropertyAccess;
import com.sencha.gxt.examples.resources.client.model.GapData;
import com.sencha.gxt.explorer.client.app.ui.ExampleContainer;
import com.sencha.gxt.explorer.client.model.Example.Detail;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.button.ToggleButton;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;

public class LineGapExample implements IsWidget, EntryPoint {

  public interface GapDataPropertyAccess extends PropertyAccess<GapData> {
    ValueProvider<GapData, Double> gapless();

    ValueProvider<GapData, Double> gapped();

    ValueProvider<GapData, String> name();

    @Path("name")
    ModelKeyProvider<GapData> nameKey();
  }

  protected static final int MIN_HEIGHT = 480;
  protected static final int MIN_WIDTH = 640;

  private static final GapDataPropertyAccess GapDataAccess = GWT.create(GapDataPropertyAccess.class);
  private static final String[] monthsFull = new String[] {
      "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November",
      "December"};

  private ContentPanel panel;

  @Override
  public Widget asWidget() {
    if (panel == null) {
      final ListStore<GapData> store = new ListStore<GapData>(GapDataAccess.nameKey());
      setupStore(store);
      
      TextSprite title = new TextSprite("Number of Hits");
      title.setFontSize(18);

      PathSprite odd = new PathSprite();
      odd.setOpacity(1);
      odd.setFill(new Color("#ddd"));
      odd.setStroke(new Color("#bbb"));
      odd.setStrokeWidth(0.5);

      NumericAxis<GapData> axis = new NumericAxis<GapData>();
      axis.setPosition(Position.LEFT);
      axis.addField(GapDataAccess.gapless());
      axis.addField(GapDataAccess.gapped());
      axis.setTitleConfig(title);
      axis.setMinorTickSteps(1);
      axis.setDisplayGrid(true);
      axis.setGridOddConfig(odd);
      axis.setMinimum(0);
      axis.setMaximum(100);
      
      title = new TextSprite("Month of the Year");
      title.setFontSize(18);

      CategoryAxis<GapData, String> catAxis = new CategoryAxis<GapData, String>();
      catAxis.setPosition(Position.BOTTOM);
      catAxis.setField(GapDataAccess.name());
      catAxis.setTitleConfig(title);
      catAxis.setLabelProvider(new LabelProvider<String>() {
        @Override
        public String getLabel(String item) {
          return item.substring(0, 3);
        }
      });
      
      Sprite marker = Primitives.square(0, 0, 6);
      marker.setFill(new RGB(194, 0, 36));

      final LineSeries<GapData> series = new LineSeries<GapData>();
      series.setLegendTitle("Gapless");
      series.setYAxisPosition(Position.LEFT);
      series.setYField(GapDataAccess.gapless());
      series.setStroke(new RGB(194, 0, 36));
      series.setShowMarkers(true);
      series.setMarkerConfig(marker);
      series.setHighlighting(true);
    
      marker = Primitives.circle(0, 0, 6);
      marker.setFill(new RGB(240, 165, 10));
    
      final LineSeries<GapData> series2 = new LineSeries<GapData>();
      series2.setLegendTitle("Gapped");
      series2.setGapless(false);
      series2.setYAxisPosition(Position.LEFT);
      series2.setYField(GapDataAccess.gapped());
      series2.setStroke(new RGB(240, 165, 10));
      series2.setShowMarkers(true);
      series2.setSmooth(true);
      series2.setMarkerConfig(marker);
      series2.setHighlighting(true);

      final Legend<GapData> legend = new Legend<GapData>();
      legend.setItemHighlighting(true);
      legend.setItemHiding(true);
      legend.getBorderConfig().setStrokeWidth(0);
      
      final Chart<GapData> chart = new Chart<GapData>();
      chart.setStore(store);
      chart.setShadowChart(false);
      chart.addAxis(axis);
      chart.addAxis(catAxis);
      chart.addSeries(series);
      chart.addSeries(series2);
      chart.setLegend(legend);
      chart.setDefaultInsets(30);

      TextButton regenerate = new TextButton("Reload Data");
      regenerate.addSelectHandler(new SelectHandler() {
        @Override
        public void onSelect(SelectEvent event) {
          setupStore(store);
          chart.redrawChart();
        }
      });
      
      ToggleButton animation = new ToggleButton("Animate");
      animation.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
        @Override
        public void onValueChange(ValueChangeEvent<Boolean> event) {
          chart.setAnimated(event.getValue());
        }
      });
      animation.setValue(true, true);
      
      ToggleButton shadow = new ToggleButton("Shadow");
      shadow.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
        @Override
        public void onValueChange(ValueChangeEvent<Boolean> event) {
          chart.setShadowChart(event.getValue());
          chart.redrawChart();
        }
      });
      shadow.setValue(false);

      ToolBar toolBar = new ToolBar();
      toolBar.add(regenerate);
      toolBar.add(animation);
      toolBar.add(shadow);

      VerticalLayoutContainer layout = new VerticalLayoutContainer();
      layout.add(toolBar, new VerticalLayoutData(1, -1));
      layout.add(chart, new VerticalLayoutData(1, 1));
      
      panel = new ContentPanel();
      panel.setHeading("Line Gap Chart");
      panel.add(layout);
    }

    return panel;
  }

  @Override
  public void onModuleLoad() {
    new ExampleContainer(this)
        .setMinHeight(MIN_HEIGHT)
        .setMinWidth(MIN_WIDTH)
        .doStandalone();
  }

  public void setupStore(ListStore<GapData> store) {
    store.clear();
    for (int i = 0; i < 12; i++) {
      if (i % 4 != 0) {
        store.add(new GapData(monthsFull[i % 12], Math.random() * 100, Math.random() * 100));
      } else {
        store.add(new GapData(monthsFull[i % 12], Double.NaN, Double.NaN));
      }
    }
  }

}
</textarea>

<script src="../../samples/ace/ace.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
  var type = "{type}";
  if (type == ("{" + "type}")) {
    // something went wrong, use java as default
    type = "java";
  }
  var editor = ace.edit("source");
  var mode = "ace/mode/" + type;
  var theme = "ace/theme/chrome";
  var readOnly = true;
  editor.getSession().setMode(mode);
  editor.getSession().setUseWorker(false);
  editor.setTheme(theme);
  editor.setShowPrintMargin(false);
  editor.renderer.setShowGutter(true);
  editor.setHighlightActiveLine(false);
  editor.setDisplayIndentGuides(true);
  editor.setReadOnly(readOnly);
  editor.renderer.setPadding(10);
  editor.renderer.setScrollMargin(10, 10, 0, 0);
  editor.getSession().setOptions({
    tabSize: 8,
    useSoftTabs: true,
    useWrapMode: false,
  });
</script>
</body>
</html>